package com.ynet.middleground.contract.service.impl;

import java.util.List;

import javax.validation.Valid;
import javax.ws.rs.Consumes;
import javax.ws.rs.POST;
import javax.ws.rs.Path;
import javax.ws.rs.Produces;
import javax.ws.rs.core.MediaType;

import org.apache.curator.shaded.com.google.common.base.Throwables;
import org.apache.dubbo.config.annotation.Service;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.util.Assert;

import com.ynet.core.common.ServiceResult;
import com.ynet.core.exception.BusinessException;
import com.ynet.core.log.IfpLogger;
import com.ynet.middleground.contract.bean.*;
import com.ynet.middleground.contract.dto.ContractDto;
import com.ynet.middleground.contract.dto.ContractNoDTO;
import com.ynet.middleground.contract.dto.NewContractDto;
import com.ynet.middleground.contract.model.ContractManagementModel;
import com.ynet.middleground.contract.service.ContractManagementService;

import io.swagger.annotations.Api;
import io.swagger.annotations.ApiImplicitParam;
import io.swagger.annotations.ApiOperation;

@Api(value = "合约管理服务", tags = {"合约管理服务"})
@Produces({MediaType.APPLICATION_JSON + "; " + "charset=UTF-8"})
@Consumes({MediaType.APPLICATION_JSON + "; " + "charset=UTF-8"})
@Path("contract")
@Service(timeout = 6000, version = "0.0.1")
public class ContractManagementServiceImpl implements ContractManagementService, GenericService {

    @Autowired
    ContractManagementModel contractManagementModel;

    @POST
    @Path("new")
    @ApiOperation(value = "新建合约",
        notes = "新建合约接口业务场景描述，渠道在新建合约时可以使用模版生成合约(制式合约)，\n" + "也可以不使用模版生成合约(非制式合约)，此接口调用使用档案模版也支持生成档案文件，并保存到档案信息表中。")
    @ApiImplicitParam(name = "requestObj", dataType = "NewContractReq", paramType = "body", required = true)
    @Override
    public ServiceResult<NewContractDto> newContract(NewContractReq requestObj) {
        ServiceResult<NewContractDto> serviceResult = new ServiceResult<>();
        NewContractDto result = null;
        try {
            result = contractManagementModel.newContract(requestObj);
            serviceResult.setResult(result);
        } catch (BusinessException be) {
            serviceResult.setError(be.getCode(), be.getMessage());
        } catch (Exception e) {
            IfpLogger.error(Thread.currentThread().getStackTrace()[1].getMethodName(), "合约管理服务异常，case: {}",
                Throwables.getStackTraceAsString(e));
            serviceResult.setError("ECCT0000", "服务异常，请联系系统管理员");
            return serviceResult;
        }
        serviceResult.setResult(result);
        return serviceResult;
    }

    @POST
    @Path("query")
    @ApiOperation(value = "查看合约", notes = "查看合约业务场景描述，用于获取合约基础信息")
    @ApiImplicitParam(name = "requestObj", dataType = "QueryContractReq", paramType = "body", required = true)
    @Override
    public ServiceResult<List<ContractDto>> queryContract(QueryContractReq requestObj) {
        ServiceResult<List<ContractDto>> serviceResult = new ServiceResult<>();
        List<ContractDto> contractDtos = null;
        try {
            contractDtos = contractManagementModel.queryContract(requestObj);
            serviceResult.setResult(contractDtos);
        } catch (BusinessException be) {
            serviceResult.setError(be.getCode(), be.getMessage());
        } catch (Exception e) {
            IfpLogger.error(Thread.currentThread().getStackTrace()[1].getMethodName(), "合约管理服务异常，case: {}",
                Throwables.getStackTraceAsString(e));
            serviceResult.setError("ECCT0000", "服务异常，请联系系统管理员");
            return serviceResult;
        }
        serviceResult.setPagerInfo(requestObj.getPagerInfo());
        serviceResult.setResult(contractDtos);
        return serviceResult;
    }

    @POST
    @Path("relation")
    @ApiOperation(value = "查看关联合约", notes = "查看关联合约业务场景描述，根据合约id作为主要查询条件，\n" + "使用渠道端业务id作为关联关系，查看合约基础信息。")
    @ApiImplicitParam(name = "requestObj", dataType = "QueryRelationContractReq", paramType = "body", required = true)
    @Override
    public ServiceResult<List<ContractDto>> queryRelationContract(QueryRelationContractReq requestObj) {
        ServiceResult<List<ContractDto>> serviceResult = new ServiceResult<>();
        List<ContractDto> contractDtos = null;
        try {
            Assert.notNull(requestObj.getContractId(), "合约Id不能空");
            contractDtos = contractManagementModel.queryRelationContract(requestObj);
            serviceResult.setResult(contractDtos);
            serviceResult.setPagerInfo(requestObj.getPagerInfo());
            serviceResult.setResult(contractDtos);
        } catch (IllegalArgumentException be) {
            serviceResult.setError("0001", be.getMessage());
        } catch (BusinessException be) {
            serviceResult.setError(be.getCode(), be.getMessage());
        } catch (Exception e) {
            IfpLogger.error(Thread.currentThread().getStackTrace()[1].getMethodName(), "合约管理服务异常，case: {}",
                Throwables.getStackTraceAsString(e));
            serviceResult.setError("ECCT0000", "服务异常，请联系系统管理员");
            return serviceResult;
        }

        return serviceResult;
    }

    @POST
    @Path("modify")
    @ApiOperation(value = "修改合约", notes = "修改合约业务场景描述，合约新建后修改合约信息，合约在审批流程退回到发起人时，\n" + "使用此接口修改合约信息")
    @ApiImplicitParam(name = "requestObj", dataType = "ModifyContractReq", paramType = "body", required = true)
    @Override
    public ServiceResult<String> modifyContract(ModifyContractReq requestObj) {
        ServiceResult<String> serviceResult = new ServiceResult<>();
        String result = null;
        try {
            result = contractManagementModel.modifyContract(requestObj);
            serviceResult.setResult(result);
        } catch (BusinessException be) {
            serviceResult.setError(be.getCode(), be.getMessage());
        } catch (Exception e) {
            IfpLogger.error(Thread.currentThread().getStackTrace()[1].getMethodName(), "合约管理服务异常，case: {}",
                Throwables.getStackTraceAsString(e));
            serviceResult.setError("ECCT0000", "服务异常，请联系系统管理员");
            return serviceResult;
        }
        serviceResult.setResult(result);
        return serviceResult;
    }

    @POST
    @Path("over")
    @ApiOperation(value = "结束合约", notes = "结束合约业务场景描述，合约状态变更为结束状态时，调用此接口。")
    @ApiImplicitParam(name = "requestObj", dataType = "OverContractReq", paramType = "body", required = true)
    @Override
    public ServiceResult<String> overContract(OverContractReq requestObj) {
        ServiceResult<String> serviceResult = new ServiceResult<>();
        String result = null;
        try {
            result = contractManagementModel.overContract(requestObj);
            serviceResult.setResult(result);
        } catch (BusinessException be) {
            serviceResult.setError(be.getCode(), be.getMessage());
        } catch (Exception e) {
            IfpLogger.error(Thread.currentThread().getStackTrace()[1].getMethodName(), "合约管理服务异常，case: {}",
                Throwables.getStackTraceAsString(e));
            serviceResult.setError("ECCT0000", "服务异常，请联系系统管理员");
            return serviceResult;
        }
        serviceResult.setResult(result);
        return serviceResult;
    }

    @POST
    @Path("change")
    @ApiOperation(value = "变更合约", notes = "变更合约业务场景描述，变更合约生成的都是非制式合约，例如：合约到期后给合约作展期。")
    @ApiImplicitParam(name = "requestObj", dataType = "ChangeContractReq", paramType = "body", required = true)
    @Override
    public ServiceResult<NewContractDto> changeContract(ChangeContractReq requestObj) {
        ServiceResult<NewContractDto> serviceResult = new ServiceResult<>();
        NewContractDto result = null;
        try {
            result = contractManagementModel.changeContract(requestObj);
            serviceResult.setResult(result);
        } catch (BusinessException be) {
            serviceResult.setError(be.getCode(), be.getMessage());
        } catch (Exception e) {
            IfpLogger.error(Thread.currentThread().getStackTrace()[1].getMethodName(), "合约管理服务异常，case: {}",
                Throwables.getStackTraceAsString(e));
            serviceResult.setError("ECCT0000", "服务异常，请联系系统管理员");
            return serviceResult;
        }
        serviceResult.setResult(result);
        return serviceResult;
    }

    @POST
    @Path("delete")
    @ApiOperation(value = "删除合约", notes = "删除合约业务场景描述，例如：新建合约后删除合约时使用。")
    @ApiImplicitParam(name = "requestObj", dataType = "DeleteContractReq", paramType = "body", required = true)
    @Override
    public ServiceResult<String> deleteContract(DeleteContractReq requestObj) {
        ServiceResult<String> serviceResult = new ServiceResult<>();
        String result = null;
        try {
            result = contractManagementModel.deleteContract(requestObj);
            serviceResult.setResult(result);
        } catch (BusinessException be) {
            serviceResult.setError(be.getCode(), be.getMessage());
        } catch (Exception e) {
            IfpLogger.error(Thread.currentThread().getStackTrace()[1].getMethodName(), "合约管理服务异常，case: {}",
                Throwables.getStackTraceAsString(e));
            serviceResult.setError("ECCT0000", "服务异常，请联系系统管理员");
            return serviceResult;
        }
        serviceResult.setResult(result);
        return serviceResult;
    }

    @POST
    @Path("modify-status")
    @ApiOperation(value = "更新合约状态服务", notes = "更新合约状态服务业务场景描述，合约状态变更为0-未签署（新建保存状态下）时调用此接口\n，"
        + "合约状态变更为：1-签署中使用此接口（开启审批流程时调用），\n" + "合约状态变更为：2-已签署使用此接口(结束审批流程时调用)")
    @ApiImplicitParam(name = "requestObj", dataType = "ModifyContractStatusReq", paramType = "body", required = true)
    @Override
    public ServiceResult<String> modifyContractStatus(ModifyContractStatusReq requestObj) {
        ServiceResult<String> serviceResult = new ServiceResult<>();
        String result = null;
        try {
            result = contractManagementModel.modifyContractStatus(requestObj);
            serviceResult.setResult(result);
        } catch (BusinessException be) {
            serviceResult.setError(be.getCode(), be.getMessage());
        } catch (Exception e) {
            IfpLogger.error(Thread.currentThread().getStackTrace()[1].getMethodName(), "合约管理服务异常，case: {}",
                Throwables.getStackTraceAsString(e));
            serviceResult.setError("ECCT0000", "服务异常，请联系系统管理员");
            return serviceResult;
        }
        serviceResult.setResult(result);
        return serviceResult;
    }

    /*@POST
    @Path("contract-submission")
    @ApiOperation(value = "确认提交合约", notes = "确认提交合约业务场景描述，新建合约或修改合约后开始审批流程并变更合约状态为签署中。")
    @ApiImplicitParam(name = "requestObj", dataType = "ContractSubmissionReq", paramType = "body", required = true)
    @Override
    public ServiceResult<ContractSubmissionDto> confirmationContractSubmission(ContractSubmissionReq requestObj) {
        ServiceResult<ContractSubmissionDto> serviceResult = new ServiceResult<>();
        ContractSubmissionDto result = null;
        try {
            result = contractManagementModel.confirmationContractSubmission(requestObj);
            serviceResult.setResult(result);
        } catch (BusinessException be) {
            serviceResult.setError(be.getCode(), be.getMessage());
        } catch (Exception e) {
            IfpLogger.error(Thread.currentThread().getStackTrace()[1].getMethodName(), "合约管理服务异常，case: {}",
                Throwables.getStackTraceAsString(e));
            serviceResult.setError("ECCT0000", "服务异常，请联系系统管理员");
            return serviceResult;
        }
        serviceResult.setResult(result);
        return serviceResult;
    }*/

    /**
     * 更新合约签署后文件地址
     *
     * @param req 更新合约签署后文件地址请求信息
     * @return 结果标志，以 success 字段值标识 true/false
     */
    @POST
    @Path("update-signed-osspath")
    @ApiOperation(value = "更新合约签署后文件地址", notes = "更新合约签署后文件地址，适用于线下签署场景，渠道将线下签署的文件上传至 OSS，再调用该服务将地址更新至中台，以作关联。")
    @ApiImplicitParam(name = "requestObj", dataType = "UpdateContractSignedPathReq", paramType = "body",
        required = true)
    @Override
    public ServiceResult<Object> updateContractSignedOssPath(@Valid UpdateContractSignedPathReq req) {
        ServiceResult<Object> result = new ServiceResult<>();
        try {
            contractManagementModel.updateContractSignedOssPath(req);
        } catch (BusinessException be) {
            result.setError(be.getCode(), be.getMessage());
        } catch (Exception e) {
            IfpLogger.error(Thread.currentThread().getStackTrace()[1].getMethodName(), "更新合约签署后文件地址服务异常, case: {}",
                com.google.common.base.Throwables.getStackTraceAsString(e));
            result.setError("ECCT0000", "服务异常，请联系系统管理员");
        }
        return result;
    }

    /**
     * 生成合约编号
     *
     * @param req 基础请求参数对象
     * @return 合约编号
     * @author liulx
     * @date 2020-12-02 10:25:29
     */
    @POST
    @Path("generate-contract-no")
    @ApiOperation(value = "生成合约编号", notes = "单独生成合约编号，适用于复杂嵌套合约场景，生成合约中有需要用到其他合约的合约编号时，可使用该服务提前生成合约编号。")
    @ApiImplicitParam(name = "requestObj", dataType = "BaseReqObj", paramType = "body", required = true)
    @Override
    public ServiceResult<ContractNoDTO> generateContarctNo(@Valid GenerateContractNoReq req) {
        ServiceResult<ContractNoDTO> result = new ServiceResult<>();
        try {
            result.setResult(contractManagementModel.generateContractNo(req));
        } catch (BusinessException be) {
            result.setError(be.getCode(), be.getMessage());
        } catch (Exception e) {
            IfpLogger.error(Thread.currentThread().getStackTrace()[1].getMethodName(), "生成合约编号服务异常, case: {}",
                com.google.common.base.Throwables.getStackTraceAsString(e));
            result.setError("ECCT0000", "服务异常，请联系系统管理员");
        }
        return result;
    }

}
